#include <REGX52.H>

sbit I2C_SCL = P0^0;
sbit I2C_SDA = P0^1;

/*********************************************************************
	方法：开始通讯
		SCL高电平期间，SDA由高电平变为低电平。
		附加动作：SCL随后变为低电平
	参数：
	返回值：无
*/
void I2C_Start(void)
{
	I2C_SDA=1;
	I2C_SCL=1;
	I2C_SDA=0;
	I2C_SCL=0;
}

/*********************************************************************
	方法：结束通讯
		SCL高电平期间，SDA由低电平变为高电平
	参数：
	返回值：无
*/
void I2C_Stop()
{
	I2C_SDA=0;
	I2C_SCL=1;
	I2C_SDA=1;
}

/*********************************************************************
	方法：发送一个字节
		SDA先赋值0/1，然后SCL先置高电平再置低电平
		循环8次，高位先发

		无论是发送还是接收数据，都是先SDA置位，然后SCL拉高再拉低；
		SCL拉高再拉低，SCL拉高期间接受方可以读取SDA的值。
		在接收数据时，需要先释放SDA（SDA置高）
	参数：
	返回值：无
*/
void I2C_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		I2C_SDA=Byte&(0x80>>i);
		I2C_SCL=1;
		I2C_SCL=0;
	}
}

/*********************************************************************
	方法：接收一个字节
		首先，释放SDA，SDA置高，由从机将SDA置位
		从机置位SDA，SCL拉高，主机读取SDA，SCL置低
		循环8次，高位在前

		无论是发送还是接收数据，都是先SDA置位，然后SCL拉高再拉低；
		SCL拉高再拉低，SCL拉高期间接受方可以读取SDA的值。
		在接收数据时，需要先释放SDA（SDA置高）
	参数：
	返回值：无
*/
unsigned char I2C_ReceiveByte(void)
{
	unsigned char i, Byte;
	I2C_SDA=1;	//释放SDA，SDA置高
	
	for(i=0;i<8;i++)
	{
		I2C_SCL=1;
		if(I2C_SDA)
		{
			Byte|=(0x80>>i);
		}
		I2C_SCL=0;
	}
	return Byte;
}

/*********************************************************************
	方法：发送应答
		SDA置位，数据0表示应答，数据1表示非应答；SCL拉高再拉低

		无论是发送还是接收数据，都是先SDA置位，然后SCL拉高再拉低；
		SCL拉高再拉低，SCL拉高期间接受方可以读取SDA的值。
		在接收数据时，需要先释放SDA（SDA置高）
	参数：数据0表示应答，数据1表示非应答
	返回值：无
*/
void I2C_SendAck(unsigned char AckBit)
{
	I2C_SDA=AckBit;
	I2C_SCL=1;
	I2C_SCL=0;
}

/*********************************************************************
	方法：接收应答
		SCL拉高，SDA读取数据，SCL拉低；数据0表示应答，数据1表示非应答

		无论是发送还是接收数据，都是先SDA置位，然后SCL拉高再拉低；
		SCL拉高再拉低，SCL拉高期间接受方可以读取SDA的值。
		在接收数据时，需要先释放SDA（SDA置高）
	参数：无
	返回值：数据0表示应答，数据1表示非应答
*/
unsigned char I2C_ReceiveAck(void)
{
	unsigned char AckBit;
	I2C_SDA=1;	//释放SDA，SDA置高
	
	I2C_SCL=1;
	AckBit= I2C_SDA;
	I2C_SCL=0;
	
	return AckBit;
}